#! /usr/bin/ruby

#Run as "./april19.rb --help" for more information.

#A cross-platform software to change Desktop Wallpaper.
# Supports - 
#  1. GNOME
# To-Support -
#  1. Windows
#  2. KDE

require 'ostruct'
require 'optparse'
require 'yaml'
GREENVIEW_VERSION = '2009.a.0.1'
class GreenView
  
  IMAGE_TYPES = /(jpe?g|png)$/i
  
  attr_accessor :verbose
  
  def initialize
    identify_platform
    @file = File.dirname(__FILE__) + '/april19.yml'
    unless File.exists? @file
      @ms = OpenStruct.new
      @ms.delay = 15
      @ms.folders = []
      File.open(@file, 'w') { |out|
        YAML::dump(@ms, out)
      }
    else
      @ms = YAML::load_file(@file)
    end

    @forest = File.dirname(__FILE__) + '/april19.forest.txt'
    File.open(@forest, 'w') {} unless File.exists? @forest
    @plants = IO.readlines(@forest)
  end
  
  def identify_platform
    @@platform = 'Gnome'
  end

  def change_wallpaper
    if @plants.size.zero?
      raise "No images found. Please run ./april19.rb --help for help"
    end
    image = File.expand_path(@plants[rand @plants.size])
    image.strip!
    any_found = false
    for i in 1..20
      any_found = true and break if File.exists? image
      puts "Image not found - #{image}"
    end
    return unless any_found
    case @@platform.downcase
      when 'gnome': system("gconftool -s /desktop/gnome/background/picture_filename -t string \"#{image}\"")
      when 'kde': 'to implement'
      when 'windows': 'to imlpement'
      when 'freebsd': 'to implement'
      else raise "Platform not supported"
    end
    puts "Wallpaper changed to #{image}."
  end
  
  #TODO:Use somekind of Timer() as in C#, also look for event of pressing 'w', and
  #change the wallpaper instantly, or for 'd' which asks for confirmation of
  #deleting a file.
  def cycle_to_change_wallpaper
    change_wallpaper
    until false
      sleep @ms.delay * 60
      change_wallpaper
    end
  end

  def show_preferences
    puts YAML::dump(@ms)
  end

  def configure_preferences
    File.open(@file, 'w') { |out|
      YAML::dump(@ms, out)
    }
    #Store image files in relative path
    images = []
    @ms.folders.each { |f|
      next unless File.exists? f.to_s
      f.chop! if f[-1].chr == '/' or f[-1].chr == "\\"
      images = recurse_for_images f
    }
    puts "\nIndexed #{images.size} files."
    images = images.join("\n")
    File.open(@forest, 'w') { |out|
      out.write(images)
    }
  end
  
  def recurse_for_images dir
    dr = []
    Dir[dir + '/*'].each { |d|
      if File.directory? d
        recurse_for_images(d).each { |f| dr << f }
      elsif d =~ IMAGE_TYPES
        puts "Indexing -- #{d}" if verbose
        dr << d
      end
    }
    dr
  end
  
  def ms
    @ms
  end
end
g = GreenView.new

configure = false
cycle = true
OptionParser.new  { |o|
  o.banner = "Usage: ./april19.rb --help\nhttp://googol.googlecode.com"
  o.on("-w", "Change wallpaper now.") { g.change_wallpaper; cycle = false }
  o.on("-p", "--preferences", "View current preferences.") { g.show_preferences; cycle = false }
  o.on("-a", "--add-folder [FOLDER]", "Add a image folder to randomly select images from.") { |v| g.ms.folders << v; configure = true; cycle = false }
  o.on("-d", "--remove-folder [FOLDER]", "Remove a folder from April19.") { |v| g.ms.folders.delete v; configure = true; cycle = false }
  o.on("--index", "Re-indices all folders for images. Usually happens automatically when folders are added or deleted.") { configure = true; cycle = false }
  o.on("--delay [MINUTES]", "Change wallpaper after this much minutes, default is 15 minutes.") { |v| g.ms.delay = v.to_i; configure = true; cycle = false }
  o.on("--verbose", "Run verbosly") { |v| g.verbose = v }
  o.on_tail("-h", "--help", "Show this help message.") { puts o; cycle = false }
  o.on_tail("-v", "--version", "Show April19 version.") { puts GREENVIEW_VERSION; cycle = false }
}.parse!

g.configure_preferences  if configure
g.cycle_to_change_wallpaper if cycle


